#pragma once

#include "CXcpObjectBase.h"
#include "NoBaseClass.h"
#include "CXcpObjectThreadSafeAddRefPolicy.h"

#include "HWFrameKeyedMutex.h"

class HWTexture;

class HWFrameKeyedMutexBuffer :
	public CXcpObjectBase<NoBaseClass,CXcpObjectThreadSafeAddRefPolicy>
{
public: 
	static HRESULT Create(struct IPALOptimizedGraphicsDevice * pUIThreadDevice, struct IPALOptimizedGraphicsDevice * pCompositorThreadDevice, HWFrameKeyedMutexBuffer * * ppHWFrameKeyedMutexBuffer);
	HRESULT EndUIThreadFrame();
	HRESULT BeginUIThreadFrame();
	HRESULT AdvanceCompositorThread(XUINT64 targetSequenceNumber);
	XUINT64 GetUIThreadSequenceNumber();
	HRESULT AddSubrectForRelease(HWTexture * pSubrectPendingRelease);

private: 
	HWFrameKeyedMutexBuffer();
	virtual ~HWFrameKeyedMutexBuffer();
	HRESULT Initialize(struct IPALOptimizedGraphicsDevice * pUIThreadDevice, struct IPALOptimizedGraphicsDevice * pCompositorThreadDevice);
	static const XUINT32 KeyedMutexPoolSize;
	xref_ptr<HWFrameKeyedMutex> m_keyedMutexes[0x5];

	XUINT64 m_uiThreadSequenceNumber;
	XUINT32 m_uiThreadIndex;
	XUINT32 m_uiThreadFrameStarted;
	XUINT64 m_compositorThreadSequenceNumber;
	XUINT32 m_compositorThreadIndex;
	XBOOL m_hasCompositorEverAdvanced;
};